package com.guo.mixframe.framework.configs


import com.guo.mixframe.framework.annotations.LoadStatic
import com.guo.mixframe.framework.exception.CoreException
import com.guo.mixframe.framework.io.Loader
import com.guo.mixframe.framework.log.LogPrint
import com.guo.mixframe.framework.utils.FileHelper
import com.guo.mixframe.framework.utils.JsonHelper
import io.vertx.core.json.JsonArray

/**
 * 分区配置
 */
@LoadStatic
class ServerConfig : Loader() {

    companion object {
        private val instance: ServerConfig

        @JvmStatic
        fun getInstance(): ServerConfig {
            return getInstance(instance, ServerConfig::class.java)
        }

        init {
            instance = getInstance()
        }
    }

    private lateinit var logicServers: List<LogicServer>
    private lateinit var gameServers: List<LogicServer>
    private lateinit var gameServersByNameId: Map<String, LogicServer>

    /**
     * 获取所有游戏分区
     */
    fun getGameServers(): List<LogicServer> {
        return useReadLock { gameServers }
    }

    /**
     * 按名称取游戏分区
     */
    fun getGameServerByNameId(nameId: String): LogicServer {
        return useReadLock {
            gameServersByNameId[nameId]
                ?: throw CoreException().throwException(CoreException.ZoneNotExist)
        }
    }

    /**
     * 按名称取局域网ip
     */
    fun getLocalIPOfZone(zoneName: String): String {
        return useReadLock { getGameServerByNameId(zoneName).localIP }
    }

    /**
     * 加载
     */
    override fun reload() {
        useWriteLock {
            //加载分区
            loadLogicServers()
            //过滤掉非法分区
            filterGameServers()

            LogPrint.logger.debug("Found ${gameServers.size} GameServers.")
        }
    }

    /**
     * 加载所有分区，并检查nameId重复
     */
    private fun loadLogicServers() {
        val jsonString = FileHelper.readStringFromClassesPath("config/servers.json")
        logicServers = JsonArray(jsonString)
            .map { JsonHelper.fromJson(it.toString(), LogicServer::class.java) }

        val serversByNameId = mutableMapOf<String, LogicServer>()

        for (logicServer in logicServers) {
            val nameId = logicServer.nameId

            if (serversByNameId.containsKey(nameId)) {
                LogPrint.logger.error("重复的逻辑服务器nameId$nameId")
            } else {
                serversByNameId[nameId] = logicServer
            }
        }
    }

    /**
     * 过滤非法分区
     */
    private fun filterGameServers() {
        gameServers = logicServers
            .asSequence()
            .filter { isNameIdValid(it) }
            .filter { isNameValid(it) }
            .toList()

        gameServersByNameId = gameServers.associateBy { it.nameId }
    }

    /**
     * 检查nameId的合法性
     * nameId必须是整数
     */
    private fun isNameIdValid(logicServer: LogicServer): Boolean {
        val nameId = logicServer.nameId

        val isNumeric = nameId.toIntOrNull() != null;
        if (!isNumeric) {
            LogPrint.logger.error("游戏服 $nameId nameId必须为非0开头的纯数字")
            return false
        }

        return true
    }

    /**
     * 检查显示名称的合法性
     * 显示名称非空
     */
    private fun isNameValid(logicServer: LogicServer): Boolean {
        if (logicServer.chName.isNullOrEmpty()) {
            LogPrint.logger.error("游戏服 ${logicServer.nameId} 未设定中文名称")
            return false
        }

        return true
    }
}
